﻿using System;
using System.Collections.Generic;
using System.Drawing;

namespace Swsk33.BasicGISGDI.Model
{
	/// <summary>
	/// 多边形类
	/// </summary>
	public class Polygon
	{
		private Point[] points;

		/// <summary>
		/// 构成多边形的点
		/// </summary>
		public Point[] Points { get => points; }

		/// <summary>
		/// 构造器依赖注入，传入点数组初始化
		/// </summary>
		/// <param name="points">传入点数组</param>
		public Polygon(Point[] points)
		{
			this.points = points;
		}

		/// <summary>
		/// 构造器依赖注入，传入点列表初始化
		/// </summary>
		/// <param name="points">传入点列表</param>
		public Polygon(List<Point> points)
		{
			this.points = points.ToArray();
		}

		/// <summary>
		/// 转角法判断传入的点是否在该多边形内
		/// </summary>
		/// <param name="point">待判断点</param>
		/// <returns>点是否在多边形内</returns>
		public bool IsPointInPolygon(Point point)
		{
			double totalArc = 0;
			Vector pointToOne, pointToTwo;
			for (int i = 0; i < points.Length; i++)
			{
				pointToOne = new Vector(point, points[i]);
				if (i == points.Length - 1)
				{
					pointToTwo = new Vector(point, points[0]);
				}
				else
				{
					pointToTwo = new Vector(point, points[i + 1]);
				}
				double arc = pointToOne.GetAngle(pointToTwo);
				// 判断方向，在窗口坐标系下，叉乘大于0为顺时针，顺时针赋值为正
				if (pointToOne.CrossProduct(pointToTwo) < 0)
				{
					arc = -arc;
				}
				totalArc = totalArc + arc;
			}
			// 绝对值
			totalArc = (int)Math.Abs(totalArc);
			// 一般来说，在多边形内角度和是360度，但是对于复杂多边形可能是360的倍数
			return totalArc / 360 >= 1;
		}

		/// <summary>
		/// 得到该多边形面积
		/// </summary>
		/// <returns>多边形面积</returns>
		public double GetArea()
		{
			double total = 0;
			Point origin = new Point(0, 0);
			Vector current, next;
			for (int i = 0; i < points.Length; i++)
			{
				current = new Vector(origin, points[i]);
				if (i == points.Length - 1)
				{
					next = new Vector(origin, points[0]);
				}
				else
				{
					next = new Vector(origin, points[i + 1]);
				}
				total = total + current.CrossProduct(next);
			}
			return Math.Abs(total / 2);
		}
	}
}